import React, { Component } from 'react';
import qq from 'inbiz-uploader/lib/dnd';

interface IDropzoneProps {
  className?: string;
  children?: any;
  dropActiveClassName?: string;
  element?: any;
  multiple?: boolean;
  onDropError?: (code: string, data: string) => void;
  onProcessingDroppedFiles?: () => void;
  onChange?: (params: any) => void;
}

class DropzoneElement extends Component<IDropzoneProps> {
  static propTypes = [
    'className',
    'children',
    'dropActiveClassName',
    'element',
    'multiple',
    'onDropError',
    'onProcessingDroppedFiles',
    'onProcessingDroppedFilesComplete',
    'onChange',
  ];

  static defaultProps = {
    dropActiveClassName: 'react-fine-uploader-gallery-dropzone-active',
  };
  private _qqDropzone: any;

  componentDidMount() {
    this._registerDropzone();
  }

  componentDidUpdate() {
    this._registerDropzone();
  }

  componentWillUnmount() {
    this._qqDropzone && this._qqDropzone.dispose();
  }

  render() {
    return (
      <div
        {...getElementProps(this.props)}
        className={`${this.props.className || ''}`}
        ref="dropZone"
      >
        {this.props.children}
      </div>
    );
  }

  _onDropError(errorCode: string, errorData: string) {
    console.error(errorCode, errorData);

    this.props.onDropError && this.props.onDropError(errorCode, errorData);
  }

  _onProcessingDroppedFilesComplete(files: any) {
    this.props.onChange && this.props.onChange(files);
  }

  _registerDropzone() {
    this._qqDropzone && this._qqDropzone.dispose();

    const dropzoneEl = this.props.element || this.refs.dropZone;

    this._qqDropzone = new qq.DragAndDrop({
      allowMultipleItems: this.props.multiple,
      callbacks: {
        dropError: this._onDropError.bind(this),
        processingDroppedFiles: this.props.onProcessingDroppedFiles || function () {},
        processingDroppedFilesComplete: this._onProcessingDroppedFilesComplete.bind(this),
      },
      classes: {
        dropActive: this.props.dropActiveClassName || '',
      },
      dropZoneElements: [dropzoneEl],
    });
  }
}

const getElementProps = (actualProps: IDropzoneProps) => {
  const actualPropsCopy = { ...actualProps };
  const expectedPropNames = DropzoneElement.propTypes;
  expectedPropNames.forEach((expectedPropName) => delete actualPropsCopy[expectedPropName]);
  return actualPropsCopy;
};

export default DropzoneElement;
